package unionpay.bestnew;

import unionpay.sdk.SDKConfig;
import unionpay.sdk.SDKUtil;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 重要：联调测试时请仔细阅读注释！
 * 
 * 产品：手机控件产�?br>
 * 交易：消费撤�?��后台资金类交易，有同步应答和后台通知应答<br>
 * 日期�?2015-09<br>
 * 版本�?1.0.0 
 * 版权�?中国银联<br>
 * 说明：以下代码只是为了方便商户测试�?提供的样例代码，商户可以根据自己�?��，按照技术文档编写�?该代码仅供参考，不提供编码�?能规范�?等方面的保障<br>
 * 交易说明:1）确定交易成功机制：商户必须�?��后台通知接口和交易状态查询接口（Form09_6_5_Query）确定交易是否成功，建议发起查询交易的机制：可查询N次（不超�?次），每次时间间�?N秒发�?即间�?�?�?�?�?6�?2S查询（查询到03�?4�?5继续查询，否则终止查询）
 *        2）消费撤�?��能对当清算日的消费做，必须为全额，一般当日或第二日到账�?
 */

public class Form05_6_3_ConsumeUndo extends HttpServlet {

	@Override
	public void init(ServletConfig config) throws ServletException {
		/**
		 * 请求银联接入地址，获取证书文件，证书路径等相关参数初始化到SDKConfig类中
		 * 在java main 方式运行时必须每次都执行加载
		 * 如果是在web应用�?���?这个方法可使用监听的方式写入缓存,无须在这出现
		 */
		//这里已经将加载属性文件的方法挪到了web/AutoLoadServlet.java�?
		//SDKConfig.getConfig().loadPropertiesFromSrc(); //从classpath加载acp_sdk.properties文件
		super.init();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		
		String merId = req.getParameter("merId");
		String orderId = req.getParameter("orderId");
		String txnTime = req.getParameter("txnTime");
		String txnAmt = req.getParameter("txnAmt");
		String origQryId = req.getParameter("origQryId");
		
		Map<String, String> data = new HashMap<String, String>();
		
		/***银联全渠道系统，产品参数，除了encoding自行选择外其他不�?���?**/
		data.put("version", SDKUtil.version);            //版本�?
		data.put("encoding", SDKUtil.encoding_UTF8);     //字符集编�?可以使用UTF-8,GBK两种方式
		data.put("signMethod", "01");                     //签名方法 目前只支�?1-RSA方式证书加密
		data.put("txnType", "31");                        //交易类型 31-消费撤销
		data.put("txnSubType", "00");                     //交易子类�? 默认00
		data.put("bizType", "000501");                    //业务类型 代收
		data.put("channelType", "07");                    //渠道类型�?7-PC�?8-手机
		
		/***商户接入参数***/
		data.put("merId", merId);             			  //商户号码，请改成自己申请的商户号或�?open上注册得来的777商户号测�?
		data.put("accessType", "0");                      //接入类型，商户接入固定填0，不�?���?
		data.put("orderId", orderId);       			  //商户订单号，8-40位数字字母，不能含�?-”或“_”，可以自行定制规则，重新产生，不同于原消费		
		data.put("txnTime", txnTime);   				  //订单发�?时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
		data.put("txnAmt", txnAmt);                       //【撤�?��额�?，消费撤�?��必须和原消费金额相同	
		data.put("currencyCode", "156");                  //交易币种(境内商户�?���?56 人民�?
		data.put("reqReserved", "透传信息");                 //请求方保留域，�?传字段（可以实现商户自定义参数的追踪）本交易的后台�?�?对本交易的交易状态查询交易�?对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字�?	
		data.put("backUrl", DemoBase.backUrl);            //后台通知地址，后台�?知参数详见open.unionpay.com帮助中心 下载  产品接口规范  网关支付产品接口规范 消费撤销交易 商户通知,其他说明同消费交易的商户通知
		
		/***要调通交易以下字段必须修�?**/
		data.put("origQryId", origQryId);   			  //【原始交易流水号】，原消费交易返回的的queryId，可以从消费交易后台通知接口中或者交易状态查询接口中获取
		
		/**请求参数设置完毕，以下对请求参数进行签名并发送http post请求，接收同步应答报�?*/
		Map<String, String> submitFromData  = SDKUtil.signData(data,SDKUtil.encoding_UTF8);  //报文中certId,signature的�?是在signData方法中获取并自动赋�?的，只要证书配置正确即可�?
		String url = SDKConfig.getConfig().getBackRequestUrl();								 //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的 acpsdk.backTransUrl
		//如果这里通讯读超时（30秒），需发起交易状�?查询交易
		Map<String, String> resmap = SDKUtil.submitUrl(submitFromData, url,SDKUtil.encoding_UTF8);//发�?请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键�?对做任何修改，如果修改会导致验签不�?�?

		/**对应答码的处理，请根据您的业务�?辑来编写程序,以下应答码处理�?辑仅供参�?------------>**/
		
		//应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规�?�?部分-附录�?
		String respCode = resmap.get("respCode") ;
		if(("00").equals(respCode)){
			//交易已受理，等待接收后台通知更新订单状�?,也可以主动发�?查询交易确定交易状�?�?
			//TODO
		}else if(("03").equals(respCode)|| 
				 ("04").equals(respCode)||
				 ("05").equals(respCode)){
			//后续�?��起交易状态查询交易确定交易状�?
			//TODO
		}else{
			//其他应答码为失败请排查原�?
			//TODO
		}
		String reqMessage = DemoBase.genHtmlResult(submitFromData);
		String rspMessage = DemoBase.genHtmlResult(resmap);
		resp.getWriter().write("请求报文:<br/>"+reqMessage+"<br/>" + "应答报文:</br>"+rspMessage+"");
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
}
